package com.gosling.gosling.mobao;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.gosling.cloudspace.common.entity.BaseResult;
import com.gosling.cloudspace.common.entity.dtos.OpenInfoDto;
import com.gosling.cloudspace.tools.MD5Tool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/***
 * ChatGPT 测试类
 * @author <a href="mailto:">lhl</a>
 */
@Slf4j
public class MobaoNetInTest {

    public static final List EMPTY_LIST = Collections.EMPTY_LIST;

//    public static final MD5 MD_5 = MD5.create();

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

    public static void main(String[] args) throws Exception {
        String payType = ",131,132,133,";
        HashSet<String> strings1 = new HashSet<>(Arrays.asList(payType.replaceFirst("[,]", "").split("[,]")));

        String aa = "," + strings1.stream().collect(Collectors.joining(",")) + ",";
        System.out.println(aa);
        System.out.println(payType);
    }



    private static void extracted1() throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
        String data = "gsfd";
        String privateKey = "9jnerlff23u8ed01np9g6ysbhsh0dvcs";
        Signature signature = Signature.getInstance("MD5withRSA");

        PKCS8EncodedKeySpec privateKeyPKCS8 = new PKCS8EncodedKeySpec(privateKey.getBytes());
        KeyFactory keyf = KeyFactory.getInstance("RSA");
        PrivateKey generatePrivate = keyf.generatePrivate(privateKeyPKCS8);

        signature.initSign(generatePrivate);
        signature.update(data.getBytes());

        byte[] singBytes = signature.sign();
        String sign = Base64.getEncoder().encodeToString(singBytes);
        System.out.println(sign);
    }

    private static void sdsada() {
        String json = "{\n" +
                "     \"accountNo\": \"20221202305095131\",\n" +
                "     \"accountType\": 2,\n" +
                "     \"address\": \"贵州省遵义市播州区平正仡佬族乡团结村半坎组\",\n" +
                "     \"agentNo\": \"90000000037\",\n" +
                "     \"apiName\": \"NET_IN\",\n" +
                "     \"apiVersion\": \"1.0.0.0\",\n" +
                "     \"bankAccountName\": \"唐韬\",\n" +
                "     \"bankName\": \"中国民生银行股份有限公司播州区支行\",\n" +
                "     \"branchBankName\": \"中国建设银行股份有限公司成都⽂庙街支行\",\n" +
                "     \"branchBankNo\": 105651000119,\n" +
                "     \"businessKind\": \"1\",\n" +
                "     \"businessLicenceNo\": \"91510100551095990X\",\n" +
                "     \"businessLicencePeriodEnd\": \"2023-05-09\",\n" +
                "     \"businessLicencePeriodStart\": \"2023-05-09\",\n" +
                "     \"businessScope\": \"法律、法规、国务院决定规定禁⽌的不得经\",\n" +
                "     \"businessType\": 1,\n" +
                "     \"cityCode\": 7030,\n" +
                "     \"contactCertNum\": \"513435199106212171\",\n" +
                "     \"contactEmail\": \"421719439@qq.com\",\n" +
                "     \"contactPerson\": \"李明\",\n" +
                "     \"contactPhone\": 15708321839,\n" +
                "     \"countyCode\": 7032,\n" +
                "     \"customerTel\": 4001002337,\n" +
                "     \"eleDataId\": \"1279\",\n" +
                "     \"icp\": 123654125,\n" +
                "     \"icpPeriodEnd\": \"2023-05-09\",\n" +
                "     \"icpPeriodStart\": \"2023-05-09\",\n" +
                "     \"icpStatus\": 1,\n" +
                "     \"legalPerson\": \"唐韬\",\n" +
                "     \"legalPersonCertNum\": \"51082119991205843X\",\n" +
                "     \"legalPersonCertPeriodEnd\": \"2023-05-09\",\n" +
                "     \"legalPersonCertPeriodStart\": \"2023-05-09\",\n" +
                "     \"legalPersonCertType\": 0,\n" +
                "     \"legalPersonNationality\": \"Chinese\",\n" +
                "     \"legalPersonSex\": 0,\n" +
                "     \"managerEmail\": \"421719439@qq.com\",\n" +
                "     \"managerTel\": 15708321839,\n" +
                "     \"mccCode\": 5398,\n" +
                "     \"merchantAttribute\": \"2\",\n" +
                "     \"merchantDomain\": \"www.shanghai.com\",\n" +
                "     \"merchantProperty\": \"2\",\n" +
                "     \"merchantType\": \"1\",\n" +
                "     \"name\": \"测试\",\n" +
                "     \"openFundSettlement\": \"D0\",\n" +
                "     \"payeeIdNum\": \"51082119991205843X\",\n" +
                "     \"platformNo\": \"M423871\",\n" +
                "     \"provinceCode\": 7000,\n" +
                "     \"registeredFund\": 20000,\n" +
                "     \"reserveMobileNo\": \"19980813240\",\n" +
                "     \"salesmanNo\": 1199,\n" +
                "     \"shareholder\": \"是的\",\n" +
                "     \"shareholder2\": \"130429198003203015\",\n" +
                "     \"shareholder3\": \"130429198003203015\",\n" +
                "     \"shareholderCertPeriodEnd\": \"2023-05-09\",\n" +
                "     \"shareholderCertPeriodEnd2\": \"2023-05-09\",\n" +
                "     \"shareholderCertPeriodStart\": \"2023-05-09\",\n" +
                "     \"shareholderCertPeriodStart2\": \"2023-05-09\",\n" +
                "     \"shareholderCertType\": 0,\n" +
                "     \"shareholderCertType2\": 0,\n" +
                "     \"shareholderCertType3\": 0,\n" +
                "     \"shareholderIdNum\": \"120221202305095131\",\n" +
                "     \"shareholderIdNum2\": \"130429198003203015\",\n" +
                "     \"shareholderType\": 0,\n" +
                "     \"shareholderType2\": 0,\n" +
                "     \"shareholderType3\": 0,\n" +
                "     \"shortName\": \"测试\"\n" +
                "}";

        //59F2CCD2588C38289B04F8D8DC667586
        String obj = JSONUtil.toJsonStr(json);
        System.out.println(obj);
        JSONObject jsonObject = JSONUtil.parseObj(obj);

        Map<String, Object> map = BeanUtil.beanToMap(jsonObject, false, true);
        System.out.println(map);
        String string = coverMap2String(map);
        //签名验证
        String privateKey = "ac3c470f60bd613c3f1396a6610e6da1";
        String data = string + privateKey;
        System.out.println(data);
        String generate = MD5Tool.generate(data);
        System.out.println(generate);
    }

    private static void ttt() throws Exception {
        String str = "accountNo=20221202305095131&accountType=2&address=贵州省遵义市播州区平正仡佬族乡团结村半坎组&agentNo=90000000037&apiName=NET_IN&apiVersion=1.0.0.0&bankAccountName=唐韬&bankName=中国民生银行股份有限公司播州区支行&branchBankName=中国建设银行股份有限公司成都⽂庙街支行&branchBankNo=105651000119&businessKind=1&businessLicenceNo=91510100551095990X&businessLicencePeriodEnd=2023-05-09&businessLicencePeriodStart=2023-05-09&businessScope=法律、法规、国务院决 定规定禁⽌的不得经&businessType=1&cityCode=7030&contactCertNum=513435199106212171&contactEmail=421719439@qq.com&contactPerson=李明&contactPhone=15708321839&countyCode=7032&customerTel=4001002337&eDataId=1297&icp=123654125&icpPeriodEnd=2023-05-09&icpPeriodStart=2023-05-09&icpStatus=1&legalPerson=唐韬&legalPersonCertNum=51082119991205843X&legalPersonCertPeriodEnd=2023-05-09&legalPersonCertPeriodStart=2023-05-09&legalPersonCertType=0&legalPersonNationality=Chinese&legalPersonSex=0&managerEmail=421719439@qq.com&managerTel=15708321839&mccCode=5398&merchantAttribute=2&merchantDomain=www.shanghai.com&merchantProperty=2&merchantType=1&name=测试&openFundSettlement=D0&payeeIdNum=51082119991205843X&platformNo=M423871&provinceCode=7000&registeredFund=20000&reserveMobileNo=19980813240&salesmanNo=1199&shareholder=是的&shareholder2=130429198003203015&shareholder3=130429198003203015&shareholderCertPeriodEnd=2023-05-09&shareholderCertPeriodEnd2=2023-05-09&shareholderCertPeriodStart=2023-05-09&shareholderCertPeriodStart2=2023-05-09&shareholderCertType=0&shareholderCertType2=0&shareholderCertType3=0&shareholderIdNum=120221202305095131&shareholderIdNum2=130429198003203015&shareholderType=0&shareholderType2=0&shareholderType3=0&shortName=测试";

        String privateKey = "ac3c470f60bd613c3f1396a6610e6da1";
        String data = str + privateKey;
        String generate = MD5Tool.generate(data);
        System.out.println(generate);
    }

    private static void 上传电子材料流程() {
        //第一步：上传文件
        String fileUrl = "https://merch2.mobaopay.com/merch/api/netIn/file/upload";
        HashMap<String, Object> fileParamMap = new HashMap<>();
        //文件名称必须为 file
        fileParamMap.put("file", new File("D:/工商信息.png"));
        fileParamMap.put("signMsg", "xxxx");
        fileParamMap.put("platformNo", "xxxx");
        fileParamMap.put("apiName", "xxxx");
        fileParamMap.put("apiVersion", "xxxx");
        //第二步：发送请求
        String result = cn.hutool.http.HttpRequest.post(fileUrl)
                //表单内容
                .form(fileParamMap)
                //超时，毫秒
                .timeout(20000)
                .execute()
                .body();
        log.info("文件上传返回结果：{}", result);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        if (jsonObject.get("retCode").equals("1")) {
            JSONObject retData = jsonObject.getJSONObject("retData");

            //第三步：拼接param和url
            HashMap<String, Object> param = new HashMap<>();
            param.put("signMsg", "xxxx");
            param.put("platformNo", "xxxx");
            param.put("apiName", "xxxx");
            param.put("apiVersion", "xxxx");
            String paramString = coverMap2String(param);
            //apiName=xxxx&apiVersion=xxxx&platformNo=xxxx&signMsg=xxxx
            String url = "https://merch2.mobaopay.com/merch/api/netIn/eData?" + paramString;

            //第四步：拼接工商信息
            HashMap<String, Object> businessInfo = new HashMap<>();
            businessInfo.put("id", retData.getStr("fileId"));
            businessInfo.put("url", retData.getStr("url"));
            businessInfo.put("mark", "businessInfo");
            businessInfo.put("name", "工商信息");
            businessInfo.put("type", "png");
            businessInfo.put("typeName", "工商信息");

            //第五步：请求体
            HashMap<String, Object> body = new HashMap<>();
            body.put("businessInfo", businessInfo);
            body.put("businessLicense", "xxxx");
            body.put("corpHandIdCard", "xxxx");
            body.put("corpIdCardBack", "xxxx");

            //第六步发送请求
            String eleResult = cn.hutool.http.HttpRequest.post(url)
                    //请求体
                    .body(JSONUtil.toJsonStr(body))
                    //超时，毫秒
                    .timeout(20000)
                    .execute()
                    .body();
            log.info("电子资料返回结果：{}", eleResult);
            //第七步：后续业务操作
        }
    }

    private static void extracted() {
        OpenInfoDto openInfoDto = new OpenInfoDto();
        openInfoDto.setCustName("41101安徽建喃建筑材料有限公司");
        openInfoDto.setEDataId("1");
        Map<String, Object> map = BeanUtil.beanToMap(openInfoDto, false, true);
        System.out.println(map);

        System.out.println(IdUtil.fastSimpleUUID());
    }

    private static void sadsa() {
        OpenInfoDto openInfoDto = new OpenInfoDto();
        openInfoDto.setCustName("41101安徽建喃建筑材料有限公司");
        openInfoDto.setPlatformNo("M423871");
        openInfoDto.setBusinessLicenceNo("915101055644648027");
        Map<String, Object> map = BeanUtil.beanToMap(openInfoDto, false, true);
        String msg = coverMap2String(map);
        openInfoDto.setSignMsg(msg);
        System.out.println(openInfoDto);

        String s = "\"id\": \"11fe74455b4649faad0112905471a8b7\"\"fileId\": \"11fe74455b4649faad0112905471a8b7\"\"name\": \"12\"\"format\": \"png\"\"size\": 59319\"url\": \"http://192.168.20.61:8503/file/downloadFile/MAXWELL/230530/11fe74455b4649faad0112905471a8b7\"";

        System.out.println(JSONUtil.toJsonStr(s));
        System.out.println(String.format(""));

//        {
//            "retCode": "1",
//            "retMsg": "success",
//            "serName": "lishizhen",
//            "retData": {
//                "id": "11fe74455b4649faad0112905471a8b7",
//                "fileId": "11fe74455b4649faad0112905471a8b7",
//                "name": "12",
//                "format": "png",
//                "size": 59319,
//                "url": "http://192.168.20.61:8503/file/downloadFile/MAXWELL/230530/11fe74455b4649faad0112905471a8b7"
//            }
//        }
    }

    public static String coverMap2String(Map<String, Object> params) {
        if (CollectionUtil.isEmpty(params)) {
            return null;
        }
        StringBuilder content = new StringBuilder();
        //用TreeMap进行排序处理 默认为ASCII规范排序
        Map<String, Object> treeMap = new TreeMap<>(String::compareTo);
        treeMap.putAll(params);
        treeMap.forEach((k, v) -> {
            //判断传入的字符串列表是否为空
            if (StringUtils.isNotBlank(k) && ObjectUtil.isNotEmpty(v)) {
                content.append("&").append(k).append("=").append(v.toString());
            }
        });
        content.delete(0, 1);
        return content.toString();
    }

    private static void lllk() {
        System.out.println(IdcardUtil.isValidCard("510522199702055572"));
        System.out.println(checkIdCard("510522199702055572"));
        //写一个校验身份证格式的方法，支持港澳台身份证号码
        boolean contains = ObjectUtil.contains("713,714", "718");
        System.out.println(contains);
        System.out.println(5 & 10);
        System.out.println(8 % 19);

        System.out.println(2 ^ 1);
        System.out.println(-4 ^ 2);
        System.out.println(64 << 1);

        System.out.println(BaseResult.success(12132312l));

        boolean isBindIp = ObjectUtil.contains("192.168.1.23", "https://192.168.1.23/")
                || ObjectUtil.contains("https://192.168.1.23/", "192.168.1.23");
        System.out.println(isBindIp);

        String ipBind = "192.168.20.61|192.168.33.76";
        String[] ips = ipBind.split("[|]");
        List<String> ipList = Arrays.asList(ips);
        if (CollectionUtil.isEmpty(ipList)) {
            System.out.println("IP格式非法！");
        }
        for (String ip : ipList) {
            boolean isIp = Validator.isUrl(ip) || Validator.isIpv4(ip) || Validator.isIpv6(ip);
            if (!isIp) {
                System.out.println("IP格式非法！");
            }
        }
    }


    /**
     * 校验身份证号码
     * 支持18位和15位身份证号码，以及港澳台的居民身份证号码
     * 校验规则如下：
     * 1、18位身份证号码校验：
     * 1）前17位必须为数字
     * 2）第18位必须为数字或大写字母X
     * 3）年份范围为1900-2100年
     * 4）月份范围为01-12月
     * 5）日期范围为01-31日
     * 6）根据前17位号码计算出的校验码必须与第18位的数字一致
     * 2、15位身份证号码校验：
     * 1）必须全为数字
     * 2）年份范围为1900-9999年
     * 3）月份范围为01-12月
     * 4）日期范围为01-31日
     * 3、港澳台居民身份证校验：
     * 1）以字母开头，后面跟着6个数字或7个数字+字母
     * 2）第7位为1或2表示男性，为3或4表示女性
     * 3）第8-10位为出生年份，以西元年表示，如1990年，则填写1990
     * 4）第11-12位为出生月份，01表示一月，12表示十二月
     * 5）第13-14位为出生日期，从01号到31号
     * 6）第15-17位为顺序号，表示在当天出生的第几个人，其中17位可能是数字或字母X
     * 7）第18位为校验码，计算方法同18位身份证
     *
     * @param idCard 身份证号码
     * @return 校验结果，true为校验通过，false为校验不通过
     */
    public static boolean checkIdCard(String idCard) {
        if (idCard == null || "".equals(idCard.trim())) { // 身份证号码不能为空
            return false;
        }

        // 判断是否为18位身份证号码
        if (idCard.length() == 18) {
            String num17 = idCard.substring(0, 17); // 取出前17位
            String num18 = idCard.substring(17); // 取出第18位

            if (!num17.matches("\\d{17}")) { // 前17位必须全部为数字
                return false;
            } else {
                int[] factors = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; // 每位号码应乘以的因子
                String[] checkCodes = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; // 校验码对应值
                int sum = 0;
                for (int i = 0; i < num17.length(); i++) { // 计算前17位号码与因子的乘积之和
                    sum += Integer.parseInt("" + num17.charAt(i)) * factors[i];
                }
                int result = sum % 11; // 取模
                if (!checkCodes[result].equals(num18)) { // 判断取模后的值是否与第18位号码相同
                    return false;
                }
            }
            String year = idCard.substring(6, 10); // 取出年份
            String month = idCard.substring(10, 12); // 取出月份
            String day = idCard.substring(12, 14); // 取出日期

            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                Date birthDate = sdf.parse(year + "-" + month + "-" + day); // 尝试转换为日期格式
                if (birthDate.after(new Date()) || !"00".equals(day) && !String.valueOf(birthDate.getDate()).equals(day)) { // 日期范围不正确
                    return false;
                }
            } catch (ParseException e) {
                e.printStackTrace();
                return false;
            }

            return true;
        }

        // 判断是否为15位身份证号码
        if (idCard.length() == 15) {
            if (!idCard.matches("\\d{15}")) { // 必须全为数字
                return false;
            }

            String year = idCard.substring(6, 8); // 取出年份
            String month = idCard.substring(8, 10); // 取出月份
            String day = idCard.substring(10, 12); // 取出日期

            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                Date birthDate = sdf.parse("19" + year + "-" + month + "-" + day); // 尝试转换为日期格式
                if (birthDate.after(new Date()) || !"00".equals(day) && !String.valueOf(birthDate.getDate()).equals(day)) { // 日期范围不正确
                    return false;
                }
            } catch (ParseException e) {
                e.printStackTrace();
                return false;
            }

            return true;
        }

        // 判断是否为港澳台居民身份证号码
        if (idCard.matches("[A-Z]\\d{6,7}[1-4]\\d{5}[0-9A]")) {
            return true;
        }

        return false;
    }
}